package com.zxing.wx.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Arrays;
import java.util.Base64;

@Slf4j
@Service
public class SignatureService {

    @Value("${wechat.public.sign-token}")
    private String token;
    @Value("${wechat.pay.private-key:123456}")
    private String private_key;
    @Value("${wechat.pay.key-v3}")
    private String key_v3;
    @Value("${wechat.pay.mch-id}")
    private String mchId;
    @Value("${wechat.pay.mch-serial-no}")
    private String mchSerialNo;

    private static final String refund_notify_url = "";

    public boolean checkSignature(String signature, String timestamp, String nonce) {
        log.info("token={}", token);
        String[] arr = {token, timestamp , nonce};
        Arrays.sort(arr);
        StringBuilder sb = new StringBuilder();
        for(String a:arr) {
            sb.append(a);
        }
        //字典顺序结果 sb
        String sha1Msg = DigestUtils.sha1Hex(sb.toString().getBytes());
        // sha1Msg 签名字符串
        return signature.equals(sha1Msg);
    }

    /**
     * 微信支付签名
     */
    public String wxPaySignature(String resourceStrs) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        byte[] bytes = resourceStrs.getBytes(StandardCharsets.UTF_8);
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(private_key.getBytes(StandardCharsets.UTF_8)));
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(merchantPrivateKey);
        sign.update(bytes);
        return Base64.getEncoder().encodeToString(sign.sign());
    }

    /**
     * 回调解密
     */
    public String decryptMessage(String body) throws JsonProcessingException, GeneralSecurityException {
        AesUtil util = new AesUtil(key_v3.getBytes(StandardCharsets.UTF_8));
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode node = objectMapper.readTree(body);
        JsonNode resource = node.get("resource");
        String ciphertext = resource.get("ciphertext").textValue();
        String associatedData = resource.get("associated_data").textValue();
        String nonce = resource.get("nonce").textValue();
        return util.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
    }

    /**
     * 微信支付验签
     */
    public boolean signVerify(String serialNumber, String message, String signature) throws GeneralSecurityException, IOException, HttpCodeException, NotFoundException {
        PrivateKey merchantPrivateKey =PemUtil.loadPrivateKey(new ByteArrayInputStream(private_key.getBytes(StandardCharsets.UTF_8)));
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey));
        certificatesManager.putMerchant(mchId, wechatPay2Credentials, key_v3.getBytes(StandardCharsets.UTF_8));
        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(mchId);
        return verifier.verify(serialNumber, message.getBytes(StandardCharsets.UTF_8), signature);
    }


}
